package com.myk.game.gobangchess.ai.symmetric;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 文件名: SurroundingPointsFinder.java
 * 功能: 提供用于查找棋块周围空位的函数。
 */
public class SurroundingPointsFinder {

    /**
     * 函数名: getSurroundingEmptyPoints
     * 函数功能: 传入一个棋块和当前棋盘，找出所有与该棋块相邻（8个方向）的空位坐标。
     *
     * @param block 输入参数, 代表一个棋块。
     *              格式: List<int[]>。
     *              这是一个坐标列表，其中每个元素 `int[]` 代表一个棋子的坐标 {row, col}。
     *              列表大小可变。
     * @param board 输入参数, 代表当前棋盘状态。
     *              格式: int[][] 数组。
     *              大小: 15x15。`1` 代表黑棋, `-1` 代表白棋, `0` 代表空位。
     *
     * @return List<int[]> 列表，包含了所有周围空位的坐标。
     *         每个坐标格式为 {row, col}。
     *         如果输入棋块为空或棋盘为null，则返回一个空列表。
     */
    public static List<int[]> getSurroundingEmptyPoints(List<int[]> block, int[][] board) {
        if (block == null || block.isEmpty() || board == null) {
            return new ArrayList<>();
        }

        // 使用HashSet来存储坐标字符串，以自动处理重复的空位
        Set<String> surroundingPoints = new HashSet<>();
        int boardSize = board.length;

        // 定义8个方向的偏移量 (上, 下, 左, 右, 及四个对角线)
        int[] dr = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dc = {-1, 0, 1, -1, 1, -1, 0, 1};

        // 遍历棋块中的每一个棋子
        for (int[] pos : block) {
            int r = pos[0];
            int c = pos[1];

            // 检查该棋子周围的8个位置
            for (int i = 0; i < 8; i++) {
                int nr = r + dr[i];
                int nc = c + dc[i];

                // 检查新坐标是否在棋盘边界内
                if (nr >= 0 && nr < boardSize && nc >= 0 && nc < boardSize) {
                    // 如果该位置是空位(0)，则将其加入Set中
                    if (board[nr][nc] == 0) {
                        surroundingPoints.add(nr + "," + nc);
                    }
                }
            }
        }

        // 将HashSet中的坐标字符串转换回 List<int[]> 格式
        List<int[]> result = new ArrayList<>();
        for (String pointStr : surroundingPoints) {
            String[] parts = pointStr.split(",");
            result.add(new int[]{Integer.parseInt(parts[0]), Integer.parseInt(parts[1])});
        }

        return result;
    }

    /**
     * main 函数用于调用和验证 getSurroundingEmptyPoints 函数。
     */
    public static void main(String[] args) {
        // 1. 初始化一个15x15的空棋盘
        int[][] board = new int[15][15];

        // 2. 定义一个用于测试的棋块
        List<int[]> sampleBlock = new ArrayList<>();
        sampleBlock.add(new int[]{0, 1});
        // sampleBlock.add(new int[]{5, 6});
        // sampleBlock.add(new int[]{6, 5});
        // sampleBlock.add(new int[]{6, 7});
        // sampleBlock.add(new int[]{7, 7});
        // sampleBlock.add(new int[]{5, 7});
        // sampleBlock.add(new int[]{7, 5});
        // sampleBlock.add(new int[]{7, 6});


        // 3. 将棋块放置到棋盘上
        for (int[] pos : sampleBlock) {
            board[pos[0]][pos[1]] = 1; // 假设是黑棋
        }
        // 在旁边放一个障碍棋子，测试是否会把它错误地识别为空位
        board[4][4] = -1; // 白棋

        System.out.println("--- 验证 getSurroundingEmptyPoints 函数 ---");
        System.out.print("输入棋块坐标: ");
        for (int[] pos : sampleBlock) {
            System.out.print(Arrays.toString(pos) + " ");
        }
        System.out.println("\n");
        System.out.println("棋盘上在(4,4)处放置了一个障碍棋子(-1)。");

        // 4. 调用函数获取周围的空位
        List<int[]> emptyPoints = getSurroundingEmptyPoints(sampleBlock, board);

        // 5. 打印输出结果
        System.out.println("函数输出结果 (周围的空位坐标):");
        if (emptyPoints.isEmpty()) {
            System.out.println("没有找到周围的空位。");
        } else {
            for (int[] point : emptyPoints) {
                System.out.print(Arrays.toString(point) + " ");
            }
            System.out.println();
        }
    }
}